package test;

import itecs.DedicatedItecs;
import itecs.Itecs;

import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;

import org.cloudbus.cloudsim.distributions.UniformDistr;

import simulation.Observation;
import util.Globals;
import models.SLA;

public class SimulationControllerTester {

	static double lambda1 = 0;
	static double lambda2 = 0;
	static SLA sla1 = null;
	static SLA sla2 = null;

	static int errors = 0;

	private static ArrayList<ArrayList<Double>> throughputObservation = new ArrayList<ArrayList<Double>>();
	private static ArrayList<ArrayList<Double>> responseObservation = new ArrayList<ArrayList<Double>>();
	private static ArrayList<ArrayList<Double>> queueLenObservation = new ArrayList<ArrayList<Double>>();
	private static ArrayList<ArrayList<Double>> utilizationObservation = new ArrayList<ArrayList<Double>>();
	private static ArrayList<ArrayList<Double>> instantUtilizationObservation = new ArrayList<ArrayList<Double>>();

	private static ArrayList<Double> throughputObservationMeans = new ArrayList<Double>();
	private static ArrayList<Double> responseObservationMeans = new ArrayList<Double>();
	private static ArrayList<Double> queueLenObservationMeans = new ArrayList<Double>();
	private static ArrayList<Double> utilizationObservationMeans = new ArrayList<Double>();
	private static ArrayList<Double> instantUtilizationObservationMeans = new ArrayList<Double>();

	private static ArrayList<Double> responseObservationVar = new ArrayList<Double>();
	private static ArrayList<Double> queueLenObservationVar= new ArrayList<Double>();
	private static ArrayList<Double> throughputObservationVar = new ArrayList<Double>();
	private static ArrayList<Double> utilizationObservationVar = new ArrayList<Double>();
	private static ArrayList<Double> instantUtilizationObservationVar = new ArrayList<Double>();



	/* calculates the stabilization campionary mean and prints
	 * it on a *.csv file
	 * USES getReplicatedRunsStabilizationMeans which calculates
	 * the means over single runs
	 */ 
	private static void writeReplicatedRunsCampionaryMean(String brokerType, String serviceType) throws IOException {

		System.out.println("Calculating RR Means..");

		queueLenObservationMeans = getReplicatedRunsStabilizationMeans(queueLenObservation);
		responseObservationMeans = getReplicatedRunsStabilizationMeans(responseObservation);
		throughputObservationMeans = getReplicatedRunsStabilizationMeans(throughputObservation);
		utilizationObservationMeans = getReplicatedRunsStabilizationMeans(utilizationObservation);
		instantUtilizationObservationMeans = getReplicatedRunsStabilizationMeans(instantUtilizationObservation);


		FileWriter file = new FileWriter("output/rr"+brokerType+"-"+lambda1+"-"+lambda2+"-"+serviceType+"-"+sla1+"-"+sla2+"means.csv", false);
		file.write("Sample size \t Queue len \t Response time \t Throughput \t Instant Utilization \t Utilization \n");

		DecimalFormat dft = new DecimalFormat("##0.00");

		for (int i=0; i<queueLenObservationMeans.size(); i++){
			file.write((i+1) + 
					"\t" + dft.format(queueLenObservationMeans.get(i)) + 
					"\t" + dft.format(responseObservationMeans.get(i)) + 
					"\t" + dft.format(throughputObservationMeans.get(0)) + 
					"\t" + dft.format(instantUtilizationObservationMeans.get(i)) + 
					"\t" + dft.format(utilizationObservationMeans.get(0)) +"\n");
		}

		file.flush();
		file.close();

		System.out.println("RR Means Calculated!");
	}


	/* calculates the stabilization campionary variance and prints
	 * it on a *.csv file
	 * USES getReplicatedRunsStabilizationMeans which calculates
	 * the means over single runs
	 */
	private static void writeReplicatedRunsCampionaryVariance(String brokerType, String serviceType) throws IOException {

		System.out.println("Calculating RR Variances..");

		ArrayList<Double> queueLenArr = queueLenObservationMeans;
		ArrayList<Double> responseArr = responseObservationMeans;
		ArrayList<Double> throughputArr = throughputObservationMeans;
		ArrayList<Double> utilizationArr = utilizationObservationMeans;
		ArrayList<Double> instantUtilizationArr = instantUtilizationObservationMeans;


		responseObservationVar.clear();
		queueLenObservationVar.clear();
		throughputObservationVar.clear();
		utilizationObservationVar.clear();
		instantUtilizationObservationVar.clear();


		for(int v = 1; v <= responseObservation.get(0).size(); v++){

			double total = 0;
			double respVar = 0;
			double queueVar = 0;
			double thrVar = 0;
			double utVar = 0;
			double iutVar = 0;

			for (int j = 0; j < responseObservation.size(); j++){

				double responseMean = 0;
				double responseSum = 0;
				double queueMean = 0;
				double queueSum = 0;
				double thrMean = 0;
				double thrSum = 0;
				double utMean = 0;
				double utSum = 0;
				double iutMean = 0;
				double iutSum = 0;
				total = 0;

				for (int i = 0; i < v - 1; i++){
					responseSum += responseObservation.get(j).get(i);
					queueSum += queueLenObservation.get(j).get(i);
					iutSum += instantUtilizationObservation.get(j).get(i);
					thrSum += throughputObservation.get(j).get(0);
					utSum += utilizationObservation.get(j).get(0);
					total++;	
				}

				if(v==1){
					responseSum += responseObservation.get(j).get(0);
					queueSum += queueLenObservation.get(j).get(0);
					iutSum += instantUtilizationObservation.get(j).get(0);
					thrSum += throughputObservation.get(j).get(0);
					utSum += utilizationObservation.get(j).get(0);
					total++;	
				}

				responseMean = responseSum/total;
				queueMean = queueSum/total;
				thrMean = thrSum/total;
				utMean = utMean/total;
				iutMean = iutMean/total;

				respVar  += (Math.pow(responseMean - responseArr.get((int)total-1), 2)/(responseObservation.size()-1))/Math.sqrt(total);
				queueVar  += (Math.pow(queueMean - queueLenArr.get((int)total-1), 2)/(queueLenObservation.size()-1))/Math.sqrt(total);
				iutVar  += (Math.pow(iutMean - instantUtilizationArr.get((int)total-1), 2)/(instantUtilizationObservation.size()-1))/Math.sqrt(total);		
				thrVar  += (Math.pow(thrMean - throughputArr.get(0), 2)/(throughputObservation.size()-1))/Math.sqrt(total);
				utVar  += (Math.pow(utMean - utilizationArr.get(0), 2)/(utilizationObservation.size()-1))/Math.sqrt(total);		
			}

			responseObservationVar.add((respVar/(responseObservation.size()-1))/total);
			queueLenObservationVar.add((queueVar/(queueLenObservation.size()-1))/total);
			throughputObservationVar.add((thrVar/(throughputObservation.size()-1))/total);
			utilizationObservationVar.add((utVar/(utilizationObservation.size()-1))/total);
			instantUtilizationObservationVar.add((iutVar/(instantUtilizationObservation.size()-1))/total);
		}


		FileWriter file = new FileWriter("output/rr"+brokerType+"-"+lambda1+"-"+lambda2+"-"+serviceType+"-"+sla1+"-"+sla2+"variances.csv", false);
		file.write("Sample Size \t Queue len V \t Response time V \t Throughput V \t Instant Utilization V \t Utilization V \n");

		DecimalFormat dft = new DecimalFormat("##0.0000");

		for (int i=0; i<responseObservationVar.size(); i++){
			file.write(((i+1)) + 
					"\t" + dft.format(queueLenObservationVar.get(i)) + 
					"\t" + dft.format(responseObservationVar.get(i)) + 
					"\t" + dft.format(throughputObservationVar.get(i))+ 
					"\t" + dft.format(instantUtilizationObservationVar.get(i))+ 
					"\t" + dft.format(utilizationObservationVar.get(i))+"\n");
		}

		file.flush();
		file.close();

		System.out.println("RR Variances Calculated!");
	}



	// calculates the n means for n runs of a replicated runs simulation
	private static ArrayList<Double> getReplicatedRunsStabilizationMeans(ArrayList<ArrayList<Double>> observation){

		ArrayList<Double> resultMeans = new ArrayList<Double>();

		int minSize = Integer.MAX_VALUE;

		for (int j = 0; j < observation.size(); j++){
			if(minSize > observation.get(j).size())
				minSize = observation.get(j).size();
		}

		for(int v = 1; v <= minSize; v++){

			double total = 0;
			double outerSum = 0;

			for (int j = 0; j < observation.size(); j++){

				double mean = 0;
				double sum = 0;
				total = 0;


				for (int i = 0; i < v; i++){
					sum += observation.get(j).get(i);
					total++;
				}

				if(v==1){
					sum += observation.get(j).get(0);
					total++;
				}

				mean = sum/total;
				outerSum  += mean;			
			}
			resultMeans.add(outerSum/observation.size());

		}

		return resultMeans;
	}






	/*  n run -> n medie sui run
	 *  n medie sui run -> media delle medie sui run
	 *  n medie sui run + media delle medie sui run -> varianza delle medie sui run
	 */
	private static double[] getMeanAndConfidenceReplicatedRun(ArrayList<ArrayList<Double>> observation){


		int size = observation.get(0).size();

		for (int j = 0; j < observation.size(); j++){
			if(size > observation.get(j).size())
				size = observation.get(j).size();
		}


		double meanSum = 0;
		double sumVar = 0;
		double the_variance = 0;
		ArrayList<Double> rowMeanObservations = new ArrayList<Double>();

		int start = Globals.SIMULATION_STABILIZATION_CLOUDLETS;
		if(size == 1)
			start = 0;

		for (int j = 0; j < observation.size(); j++){

			double sum = 0;

			for(int i = start; i < size; i++){
				sum += observation.get(j).get(i);
			}

			meanSum += sum/(size - start);
			rowMeanObservations.add(sum/(size - start));
		}

		double the_mean = meanSum/observation.size();


		for (int j = 0; j < rowMeanObservations.size(); j++){
			sumVar += Math.pow(rowMeanObservations.get(j) - the_mean, 2);
		}

		the_variance = sumVar/(rowMeanObservations.size()-1);

		double dt = Globals.U_95_PERCENT*(Math.sqrt(the_variance)/Math.sqrt(rowMeanObservations.size()));

		double[] res = new double[3];
		res[0] = the_mean;
		res[1] = the_mean - dt;
		res[2] = the_mean + dt;

		System.out.println("Observed Mean: " + res[0]);
		System.out.println("95% Confidence Interval: [" + res[1] + ", " + res[2] + "]");
		System.out.println("Confidence Interval size : " + (res[2] - res[1]));

		return res;
	}

	public static void clearObservations(){
		throughputObservation.clear();
		responseObservation.clear();
		queueLenObservation.clear();
		utilizationObservation.clear();
		instantUtilizationObservation.clear();
	}

	/* gets the observation ArrayList and splits it in type separated observations
	 */
	public static void splitObservations(ArrayList<Observation> obs, double th, double U){

		ArrayList<Double> respT = new ArrayList<Double>();
		ArrayList<Double> queueL = new ArrayList<Double>();
		ArrayList<Double> throughP = new ArrayList<Double>();
		ArrayList<Double> utilizations = new ArrayList<Double>();
		ArrayList<Double> instantUtilizations = new ArrayList<Double>();

		int cloudletLimit = Globals.SIMULATION_STABILIZATION_CLOUDLETS + Globals.SIMULATION_CLOUDLETS;

		if(obs.size() < cloudletLimit){
			System.err.println("ERROR: not enough observations!!!!!");
			cloudletLimit = obs.size();
			//System.exit(-1);
			errors++;
		}


		for(int j = 0; j < cloudletLimit; j++){
			respT.add(obs.get(j).getResponseTime());
			queueL.add(obs.get(j).getQueueLen());
			instantUtilizations.add(obs.get(j).getIU());
		}

		throughP.add(th);
		utilizations.add(U);

		responseObservation.add(respT);
		queueLenObservation.add(queueL);
		instantUtilizationObservation.add(instantUtilizations);
		throughputObservation.add(throughP);
		utilizationObservation.add(utilizations);
	}

	private static int getStabilizationTime() {
		// calcola la media campionaria
		double partialMean = 0;
		double previousMean = 0;
		double variance = 0;
		double previousVariance = 0;
		double STABLE_SYSTEM_TRESHOLD = 1000;
		int j = 0;
		for (int i = 0; i < responseObservationMeans.size(); i++) {

			partialMean = responseObservationMeans.get(i);
			variance = responseObservationVar.get(i);

			//System.out.println("Variance:" + variance);

			if (Math.abs(partialMean - previousMean) <= 0.04 &&  Math.abs(variance - previousVariance)<=0.01 ) {
				//System.out.println("Ora provo a stabilizzarmi qui: " + i);
				//System.out.println("Diff:" + Math.abs(partialMean - previousMean));
				//System.out.println("Diff var: " + Math.abs(variance - previousVariance));
				previousMean = partialMean;
				previousVariance = variance;
				for (j = i + 1; j <= i + STABLE_SYSTEM_TRESHOLD; j++) {
					if (j>=responseObservationMeans.size()){
						System.out.println("SISTEMA NON STABILE A:" + j + "\n");	
						return -1;
					}
					partialMean = responseObservationMeans.get(j);
					variance = responseObservationVar.get(j);

					if (Math.abs(partialMean - previousMean) >= 0.04 || Math.abs(variance - previousVariance) >= 0.01) {
						//System.out.println(j + ") NON SE STABILIZZA!");
						break;
					}
					if (j == STABLE_SYSTEM_TRESHOLD + i -1 ) {
						System.out.println("SISTEMA STABILE A:" + j + "\n");
						return j;
					}
				}


			}

			previousMean =responseObservationMeans.get(i);
			previousVariance = responseObservationVar.get(i);
		}
		System.out.println("SISTEMA NON STABILE A:" + j + "\n");	
		return -1;

	}

	public static void main2(String args[]){

		FileWriter file;
		try {
			file = new FileWriter("output/eval.csv", true);
			file.write("lambda1 \t lambda2 \t traffic type \t sla1 \t sla2  \t mu \t FCFS-DA m1 \t FCFS-DA m2 \t FCFS-DA tot \t FCFS-SA \t HOL \t PDP\n");
			file.flush();
			file.close();
		} catch (IOException e) {
			e.printStackTrace();
		}


		ArrayList<ArrayList<Integer>> strategiesEval = new ArrayList<ArrayList<Integer>>();



		String serviceDistribution = "PARETO";

		int l1 = 5;
		int l2 = 15;

		sla1 = new SLA(40, 0.8);
		sla2 = new SLA(45, 0.95);




		try {

			file = new FileWriter("output/evalstab.csv", true);
			file.write("brokerType" + "\t" + "trafficType" + "\t"  + "lambda1" + "\t"  + "lambda2" + "\t" + "sla1" + "\t" + "sla2" + "\t" + "numberOfServers" + "\t" + "stabilization" + "\n");
			file.flush();
			file.close();

			file = new FileWriter("output/stabilization.csv", true);
			file.write("lambda1 \t lambda2 \t sla1 \t sla2 \t broker \t traffic type \t stabilization cloudlets\n");
			file.flush();
			file.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		System.gc();

		if(serviceDistribution.equals("EXP"))
			Globals.SIMULATION_TIME = 2.5*(Globals.SIMULATION_STABILIZATION_CLOUDLETS + Globals.SIMULATION_CLOUDLETS)/(l1 + l2);
		else
			Globals.SIMULATION_TIME = 5*(Globals.SIMULATION_STABILIZATION_CLOUDLETS + Globals.SIMULATION_CLOUDLETS)/(l1 + l2);


		System.out.println("Heuristic simulation time: " + Globals.SIMULATION_TIME);
		System.out.println();
		System.out.println();

		lambda1 = l1;
		lambda2 = l2;

		// FCFS dedicated allocation simulation
		int numberOfDedicatedServers = 0;
		int dedicatedServers[] = new int[2];
		String brokerType = "FCFS-DA";
		clearObservations();

		try {
			//dedicatedServers[0]=26;
			//dedicatedServers[1]=26;
			dedicatedServers = DedicatedItecs.getDedicatedOptimalM(serviceDistribution, sla1, sla2, lambda1, lambda2);

			if (dedicatedServers == null) {
				System.out.println("Impossibile rispettare gli SLA con questi parametri.");
				System.exit(-1);
			}

			numberOfDedicatedServers = dedicatedServers[0] + dedicatedServers[1];

			DedicatedItecs itecs = new DedicatedItecs(sla1, sla2, serviceDistribution, lambda1, lambda2);

			for (int i=0; i<Globals.SEEDS.length; i++){
				itecs.startDedicatedWithParams(Globals.SEEDS[i], dedicatedServers[0], dedicatedServers[1]);
				itecs.printDedicatedStats();
				System.out.println(brokerType + " obs size: " + itecs.getObservations().size());
				splitObservations(itecs.getObservations(), itecs.getRunThroughput(), itecs.getUtilization());
			}



			if(Globals.STABILIZATION_ONLY){
				writeReplicatedRunsCampionaryMean(brokerType, serviceDistribution);
				writeReplicatedRunsCampionaryVariance(brokerType, serviceDistribution);

				int stabilization = getStabilizationTime();

				try {
					file = new FileWriter("output/evalstab.csv", true);
					file.write(brokerType + "\t" + serviceDistribution + "\t"  + lambda1 + "\t"  + lambda2 + "\t" + sla1 + "\t" + sla2 + "\t" +numberOfDedicatedServers + "\t" + stabilization + "\t" + dedicatedServers[0] + "\t" + dedicatedServers[1]+ "\n");
					file.flush();
					file.close();

					file = new FileWriter("output/stabilization.csv", true);
					file.write(lambda1 + "\t"  + lambda2 + "\t" + sla1 + "\t" + sla2 + "\t" + brokerType + "\t" + serviceDistribution + "\t" + stabilization  + "\n");
					file.flush();
					file.close();
				} catch (IOException e) {
					e.printStackTrace();
				};

			}


			if(Globals.OBSERVATION_STUDY_ONLY){
				System.out.println("\nMean and confidence intervals for RESPONSE TIME");
				getMeanAndConfidenceReplicatedRun(responseObservation);

				System.out.println("\nMean and confidence intervals for QUEUE LENGTH");
				getMeanAndConfidenceReplicatedRun(queueLenObservation);

				System.out.println("\nMean and confidence intervals for THROUGHPUT");
				getMeanAndConfidenceReplicatedRun(throughputObservation);

				System.out.println("\nMean and confidence intervals for INSTANT UTILIZATION");
				getMeanAndConfidenceReplicatedRun(instantUtilizationObservation);

				System.out.println("\nMean and confidence intervals for UTILIZATION");
				getMeanAndConfidenceReplicatedRun(utilizationObservation);
			}


		} catch (Exception e) {
			e.printStackTrace();
		}


		// FCFS, HOL, PDP shared allocation
		String[] brokerTypes = {"FCFS", "HOL", "PDP"};
		int[] numberOfSharedServers = {0,0,0};

		for(int b = 0; b < brokerTypes.length; b++){

			brokerType = brokerTypes[b];
			clearObservations();

			try {

				numberOfSharedServers[b] = Itecs.getOptimalM(brokerType, sla1, sla2, lambda1, lambda2, serviceDistribution);

				if (numberOfSharedServers[b] == -1) {
					System.out
					.println("Impossibile rispettare gli SLA con questi parametri.");
					System.exit(-1);
				}

				Itecs itecs = new Itecs(brokerType, sla1, sla2, "EXP", lambda1, lambda2);

				for (int i=0; i<Globals.SEEDS.length; i++){
					itecs.startWithParams(Globals.SEEDS[i], numberOfSharedServers[b]);
					itecs.printStats();
					System.out.println(brokerType + " obs size: " + itecs.getObservations().size());
					splitObservations(itecs.getObservations(), itecs.getRunThroughput(), itecs.getUtilization());
				}

				if(Globals.STABILIZATION_ONLY){
					writeReplicatedRunsCampionaryMean(brokerType, serviceDistribution);
					writeReplicatedRunsCampionaryVariance(brokerType, serviceDistribution);

					int stabilization = getStabilizationTime();

					try {
						file = new FileWriter("output/evalstab.csv", true);
						file.write(brokerType + "\t" + serviceDistribution + "\t"  + lambda1 + "\t"  + lambda2 + "\t" + sla1 + "\t" + sla2 + "\t" + numberOfSharedServers[b] + "\t" + stabilization + "\n");
						file.flush();
						file.close();


						file = new FileWriter("output/stabilization.csv", true);
						file.write(lambda1 + "\t"  + lambda2 + "\t" + sla1 + "\t" + sla2 + "\t" + brokerType + "\t" + serviceDistribution + "\t" + stabilization  + "\n");
						file.flush();
						file.close();
					} catch (IOException e) {
						e.printStackTrace();
					};
				}

				if(Globals.OBSERVATION_STUDY_ONLY){

					System.out.println("\nMean and confidence intervals for RESPONSE TIME");
					getMeanAndConfidenceReplicatedRun(responseObservation);

					System.out.println("\nMean and confidence intervals for QUEUE LENGTH");
					getMeanAndConfidenceReplicatedRun(queueLenObservation);

					System.out.println("\nMean and confidence intervals for THROUGHPUT");
					getMeanAndConfidenceReplicatedRun(throughputObservation);

					System.out.println("\nMean and confidence intervals for INSTANT UTILIZATION");
					getMeanAndConfidenceReplicatedRun(instantUtilizationObservation);

					System.out.println("\nMean and confidence intervals for UTILIZATION");
					getMeanAndConfidenceReplicatedRun(utilizationObservation);
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
		}



		try {
			file = new FileWriter("output/eval.csv", true);
			file.write(lambda1 + "\t"  + lambda2 + "\t" + serviceDistribution + "\t" + sla1 + "\t" + sla2 + "\t" + (1/Globals.CLOUDLET_LENGTH_MEAN)/Globals.VM_MIPS + "\t" +
					dedicatedServers[0]+ "\t" + dedicatedServers[1] + "\t" + numberOfDedicatedServers + "\t" + numberOfSharedServers[0] + "\t" + numberOfSharedServers[1] + "\t" + numberOfSharedServers[2] + "\n");
			file.flush();
			file.close();



			System.out.println("FCFS-da: " + dedicatedServers[0]+ "-" + dedicatedServers[1] + " (" + numberOfDedicatedServers + ")\nFCFS-sa: " + numberOfSharedServers[0] + "\nHOL: " + numberOfSharedServers[1] + "\nPDP: " + numberOfSharedServers[2]);

			ArrayList<Integer> singleIterationMs = new ArrayList<Integer>();
			singleIterationMs.add(numberOfDedicatedServers);
			singleIterationMs.add(numberOfSharedServers[0]);
			singleIterationMs.add(numberOfSharedServers[1]);
			singleIterationMs.add(numberOfSharedServers[2]);

			strategiesEval.add(singleIterationMs);
			System.err.println("ERRORS: " + errors);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	public static void main(String[] args) {


		try {
			int lower = 12;
			int upper = 17;
			int gSlaCouples = 30;

			UniformDistr ud1=new UniformDistr(lower, upper, Globals.SEEDS[0]);
			UniformDistr ud2=new UniformDistr(lower, upper, Globals.SEEDS[1]);

			double x1 = ud1.sample();
			double x2 = ud2.sample();

			double yarray[] = { 0.80, 0.85, 0.90, 0.95 };
			double y1 = yarray[(int) (ud1.sample() % yarray.length)];
			double y2 = yarray[(int) (ud2.sample() % yarray.length)];

			String[] serviceDistributions = { "EXP" };
			String[] brokerTypes = { "FCFS", "HOL", "PDP" };

			int ms[] = new int[brokerTypes.length];

//			int lambdaStart = 5;
//			int lambdaEnd = 20;
//			int lambdaJump = 5;

			int totalrun = 0;
			int confcounter = 0;
			int confScore[] = new int[brokerTypes.length];
			SLA slas[][] = new SLA[2][gSlaCouples];

			String serviceDistribution = null;

			FileWriter f = new FileWriter("output/ms.csv", false);
			f.write("Service \t SLA1 \t SLA2 \t l1 \t l2 \t FCFS-DA1 \t FCFS-DA2 \t FCFS-DA-tot \t FCFS \t HOL \t PDP \n");

			for (int i = 0; i < gSlaCouples; i++) {
				x1 = ud1.sample();
				y1 = yarray[(int) (ud1.sample() % yarray.length)];
				x2 = ud2.sample();
				y2 = yarray[(int) (ud2.sample()%yarray.length)];
				SLA sla1 = new SLA(x1, y1);
				SLA sla2 = new SLA(x2, y2);
				slas[0][i] = sla1;
				slas[1][i] = sla2;
			}
			for (int i = 0; i < Globals.GSLAS.length; i++) {

				sla1 = Globals.GSLAS[i][0].getSla();
				sla2 = Globals.GSLAS[i][1].getSla();

				for (int j = 0; j < serviceDistributions.length; j++) {

					serviceDistribution = serviceDistributions[j];

					//					for (int l1 = lambdaStart; l1 < lambdaEnd; l1 += lambdaJump) {
					//						for (int l2 = lambdaStart; l2 < lambdaEnd; l2 += lambdaJump) {
					//							if (l1 + l2 > lambdaEnd)
					//		continue;
					
					int l1 = 15;
					int l2 = 5;

					int minScore = Integer.MAX_VALUE;
					int dedicatedm1 = 0;
					int dedicatedm2 = 0;

					for (int b = 0; b < brokerTypes.length; b++) {

						String type = brokerTypes[b];
						
						try {
							f = new FileWriter("output/mmmmm.csv", true);
							f.write("broker \t sla1 \t sla2 \t t1 \t t2 \n");
							f.flush();
							f.close();
						} catch (IOException e) {
							e.printStackTrace();
						}

						ms[b] = Itecs.getOptimalM(type, sla1, sla2, l1, l2, serviceDistribution);
						if (minScore > ms[b]) {
							minScore = ms[b];
						}
						totalrun++;





					}
					confcounter++;
					f.write(serviceDistribution + "\t" + sla1 + "\t" + sla2 + "\t" + l1 + "\t" + l2 +"\t" + dedicatedm1 +"\t" + dedicatedm2 + "\t");
					for (int e=0; e<ms.length; e++){
						f.write(ms[e] + "\t");
					}
					f.write("\n");
					f.flush();
					for (int k = 0; k < ms.length; k++) {
						if (ms[k] == minScore) {
							confScore[k]++;
						}
						//							}
						//						}
						//
					}
					FileWriter f2 = new FileWriter("output/scores.csv", true);
					f2.write(serviceDistribution + "\t");

					for (int e = 0; e < confScore.length; e++) {
						f2.write((((double)confScore[e] /(double) confcounter)*100) + "\t");
					}
					f2.write("\n");
					f2.flush();
					f2.close();

				}


			}
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
